#!/usr/bin/env python3
"""
RTSP流YOLOv8检测与推流系统
功能：
1. 从RTSP获取视频流
2. 使用YOLOv8进行目标检测（人、杯子、火焰）
3. 将处理后的视频通过RTSP推流
4. 检测到危险时自动录制视频
"""

import sys
import signal
import time
import argparse
from pathlib import Path
import os
import subprocess

# 添加项目根目录到Python路径
sys.path.append(str(Path(__file__).parent))

from src.utils.config_loader import ConfigLoader
from src.core.stream_manager import StreamManager
# from web_api_server import run_server


class RTSPDetectionSystem:
    def __init__(self, config_dir: str = "config"):
        """初始化RTSP检测系统"""
        print("=" * 50)
        print("RTSP流YOLOv8检测与推流系统")
        print("=" * 50)

        # 加载配置
        self.config_loader = ConfigLoader(config_dir)   # 自动加载config目录下的config.yaml文件
        self.stream_manager = None                      # 流管理器，用于管理RTSP流

        # 设置信号处理
        signal.signal(signal.SIGINT, self._signal_handler)  # 处理Ctrl+C信号
        signal.signal(signal.SIGTERM, self._signal_handler) # 处理终止信号

    def _signal_handler(self, signum, frame):
        """处理退出信号"""
        print("\n接收到退出信号，正在关闭系统...")
        self.stop()
        sys.exit(0)


    def start(self):
        """启动系统"""
        try:
            print("\n正在初始化系统组件...")

            # 创建流管理器
            self.stream_manager = StreamManager(self.config_loader)  # 创建流管理器，传入配置

            # 启动流管理器
            if not self.stream_manager.start():
                print("系统启动失败")
                return False

            print("\n系统启动成功！")
            print(f"输入RTSP流: {self.config_loader.app_config['rtsp']['input_url']}")

            # 显示推流和观看地址
            print(f"推流地址: {self.config_loader.app_config['rtsp']['output_url']}")
            print(f"观看地址: {self.config_loader.app_config['rtsp']['view_url']}")

            print("\n提示：")
            print("- 使用VLC,ffplay等播放器打开观看地址查看结果")
            print("- 检测到危险物品（火焰）时会自动录制视频,触发警告")
            print("- 按Ctrl+C退出程序")
            print("-" * 50)

            # 保持运行
            while True:
                time.sleep(1)

        except Exception as e:
            print(f"系统运行错误: {e}")
            import traceback
            traceback.print_exc()
            return False

    def stop(self):
        """停止系统"""
        if self.stream_manager:
            self.stream_manager.stop()
        print("系统已停止")


class MediaMTXManager:
    def __init__(self):
        self.process = None

    def start(self):
        """启动mediamtx"""
        mediamtx_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "mediamtx_v1.13.0_windows_amd64")
        mediamtx_exe = os.path.join(mediamtx_dir, "mediamtx.exe")
        mediamtx_yml = os.path.join(mediamtx_dir, "mediamtx.yml")

        if not os.path.exists(mediamtx_exe):
            print(f"未找到mediamtx.exe: {mediamtx_exe}")
            return 
        #  在命令行中启动 mediamtx 
        self.process = subprocess.Popen(
            [mediamtx_exe, mediamtx_yml],   
            cwd=mediamtx_dir,
            creationflags=subprocess.CREATE_NEW_CONSOLE
        )
        print("MediaMTX已启动")

    def stop(self):
        """停止mediamtx"""
        if self.process and self.process.poll() is None:
            # 先尝试优雅终止
            self.process.terminate()
            try:
                self.process.wait(timeout=5)
            except subprocess.TimeoutExpired:
                # 如果5秒还没关掉，强制杀死
                self.process.kill()
            print("MediaMTX已关闭")


def main():
    """主函数"""
    parser = argparse.ArgumentParser(description='RTSP流YOLOv8检测与推流系统')
    parser.add_argument('--config', type=str, default='config',
                        help='配置文件目录路径')
    parser.add_argument('--test', action='store_true',
                        help='测试模式（检查组件是否正常）')

    args = parser.parse_args()

    # 创建系统实例
    system = RTSPDetectionSystem(args.config)

    if args.test:
        print("运行测试模式...")
        # 这里可以添加测试逻辑
        print("测试完成")
    else:
        # 启动系统
        system.start()


if __name__ == "__main__":
    mediamtx_manager = MediaMTXManager()
    mediamtx_manager.start()
    time.sleep(1)
    try:
        main()
    finally:
        mediamtx_manager.stop()
